﻿using System;
using Autodesk.Revit.DB;
using YArchitech.Revit;

namespace FetchDataCompare
{
	internal class DimGeoObject : GeoObjectBase
	{
		public DimGeoObject(Element inputElement)
		{
			base.GeoObjType = EGeoObjectType.eDimObj;
			this.InitDataByElement(inputElement);
		}

		public override void InitDataByElement(Element inputElement)
		{
			Dimension dimension = inputElement as Dimension;
			if (dimension == null)
			{
				base.BoundingRect.LeftBottom = XYZ.Zero;
				base.BoundingRect.RightTop = XYZ.Zero;
				return;
			}
			try
			{
				if (dimension.DimensionShape == null)
				{
					double value = 0.0;
					Line linearDimCurve = this.GetLinearDimCurve(dimension, ref value);
					this.InitBoundingRectByLine(linearDimCurve, value, dimension.View.ViewDirection);
				}
                else if ((int)dimension.DimensionShape == 2 || (int)dimension.DimensionShape == 5)
				{
					this.InitBoundingRectByPoint(dimension.Origin, dimension.View, dimension.Value.Value);
				}
                else if ((int)dimension.DimensionShape == 1 || (int)dimension.DimensionShape == 3)
				{
					Arc arc = dimension.Curve as Arc;
					this.InitBoundingRectByArc(arc, dimension.Origin, arc.Radius);
				}
                else if ((int)dimension.DimensionShape == 4)
				{
					LocationPoint locationPoint = dimension.Location as LocationPoint;
					XYZ point = locationPoint.Point;
					this.InitBoundingRectByPoint(point, dimension.View, 2.0);
				}
				else
				{
					base.BoundingRect.LeftBottom = XYZ.Zero;
					base.BoundingRect.RightBottom = XYZ.Zero;
					base.BoundingRect.LeftTop = XYZ.Zero;
					base.BoundingRect.RightTop = XYZ.Zero;
				}
			}
			catch (Exception)
			{
				base.BoundingRect.LeftBottom = XYZ.Zero;
				base.BoundingRect.RightBottom = XYZ.Zero;
				base.BoundingRect.LeftTop = XYZ.Zero;
				base.BoundingRect.RightTop = XYZ.Zero;
			}
		}

		private void InitBoundingRectByLine(Line line, double value, XYZ normal)
		{
			XYZ xyz = line.Origin;
			XYZ direction = line.Direction;
			XYZ xyz2 = xyz.Add(direction * value);
			Transform transform = Transform.CreateRotationAtPoint(normal, -Math.PI*.5, xyz);
			Transform transform2 = Transform.CreateRotationAtPoint(normal, Math.PI*.5, xyz);
			xyz = xyz.Add(transform2.OfVector(direction) * 1.0);
			xyz2 = xyz2.Add(transform.OfVector(direction) * 1.0);
			base.BoundingRect.LeftBottom = xyz;
			base.BoundingRect.RightBottom = xyz.Add(direction * value);
			base.BoundingRect.LeftTop = xyz2.Add(-direction * value);
			base.BoundingRect.RightTop = xyz2;
		}

		private void InitBoundingRectByArc(Arc arc, XYZ origin, double angle)
		{
			XYZ center = arc.Center;
			XYZ xyz = (origin - center).Normalize();
			double num = 2.0 * arc.Radius * Math.Sin(angle);
			Transform transform = Transform.CreateRotationAtPoint(arc.Normal, -Math.PI*.5, center);
			XYZ xyz2 = transform.OfVector(xyz);
			Transform transform2 = Transform.CreateRotationAtPoint(arc.Normal, Math.PI*.5, center);
			XYZ xyz3 = transform2.OfVector(xyz);
			base.BoundingRect.LeftBottom = center.Add(xyz2 * num / 2.0);
			base.BoundingRect.RightBottom = center.Add(xyz3 * num / 2.0);
			base.BoundingRect.LeftTop = origin.Add(xyz2 * num / 2.0);
			base.BoundingRect.RightTop = origin.Add(xyz3 * num / 2.0);
		}

		private void InitBoundingRectByPoint(XYZ location, View view, double value)
		{
			XYZ rightDirection = view.RightDirection;
			XYZ upDirection = view.UpDirection;
			XYZ xyz = -upDirection;
			XYZ xyz2 = -rightDirection;
			XYZ xyz3 = location.Add(rightDirection * value);
			XYZ xyz4 = location.Add(xyz2 * value);
			base.BoundingRect.RightTop = xyz3.Add(upDirection * value);
			base.BoundingRect.RightBottom = xyz3.Add(xyz * value);
			base.BoundingRect.LeftTop = xyz4.Add(upDirection * value);
			base.BoundingRect.LeftBottom = xyz4.Add(xyz * value);
		}

		public override bool Equals(object obj)
		{
			return base.Equals(obj);
		}

		public Line GetLinearDimCurve(Dimension dimension, ref double length)
		{
			XYZ xyz;
			XYZ xyz2;
			if (dimension.NumberOfSegments == 0)
			{
				XYZ origin = dimension.Origin;
				Line line = dimension.Curve as Line;
				XYZ direction = line.Direction;
				length = dimension.GetParameter("总长度").AsDouble();
				xyz = origin.Add(direction * length / 2.0);
				xyz2 = origin.Add(-direction * length / 2.0);
			}
			else
			{
				DimensionSegmentArray segments = dimension.Segments;
				DimensionSegment dimensionSegment = segments.get_Item(0);
				XYZ origin2 = dimensionSegment.Origin;
				DimensionSegment dimensionSegment2 = segments.get_Item(dimension.NumberOfSegments - 1);
				XYZ origin3 = dimensionSegment2.Origin;
				XYZ xyz3 = (origin3 - origin2).Normalize();
				xyz = origin2.Add(-xyz3 * dimensionSegment.Value.Value / 2.0);
				xyz2 = origin3.Add(xyz3 * dimensionSegment2.Value.Value / 2.0);
				length = xyz.DistanceTo(xyz2);
			}
			return Line.CreateBound(xyz, xyz2);
		}
	}
}
